/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[FileUploadServlet.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package file.upload.api;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet3.0提供了上传文件的注解<br/>
 * 
 * 使用注解 @MultipartConfig 将一个Servlet标识为支持文件上传<br/>
 * Servlet 3.0 将multipart/form-data的post请求封装成为一个Part, 通过Part对上传的文件进行操作<br/>
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
@MultipartConfig(fileSizeThreshold = 1024 * 500, location = "z:/temp", maxFileSize = 1048576, maxRequestSize = 5242880)
@WebServlet(name = "FileUploadServlet", urlPatterns = "/apiUpload")
public class FileUploadServlet extends HttpServlet {

	private static final long serialVersionUID = 7028715167219432861L;
	private static final String fileNameExtractorRegex = "filename=\".+\"";
	private static final MultipartConfig config;

	static {
		config = FileUploadServlet.class.getAnnotation(MultipartConfig.class);
		String location = config.location();
		File file = new File(location);
		if (!file.exists()) {
			file.mkdirs();
		}
		// 在doPost方法里面可以读取MultiConfig的各种配置信息对文件大小, 文件数量等做检查
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		request.setCharacterEncoding("UTF-8");

		// 获得上传的文件集合
		Collection<Part> parts = request.getParts();

		if (parts != null && !parts.isEmpty()) {
			for (Part part : parts) {
				// 过滤空文件
				if (part == null) {
					continue;
				}
				// Part part = request.getPart("file1");// 通过表单控件名获取Part对象
				String fileName = getFileName(part);
				// 只有含有content-type的表单控件才上传
				if (part.getContentType() != null) {
					part.write(fileName);
				}
			}
		}

		request.getRequestDispatcher("/jsp/fileupload/servletapi/upload.jsp").forward(request, response);
	}

	/**
	 * 根据请求头解析出文件名<br/>
	 * 
	 * 在不同的浏览器下 headerContent的内容稍有区别<br/>
	 * firefox/chrome: headerInfo={form-data,name="file",filename="1.jpg"}<br/>
	 * IE: headerInfo={form-data,name="file",filename="Z:\1.jpg"}
	 * 
	 * @param header
	 * @return
	 */
	private String getFileName(Part part) {
		String headerContent = part.getHeader("content-disposition");
		String fileName = "";

		Pattern pattern = Pattern.compile(fileNameExtractorRegex);
		Matcher matcher = pattern.matcher(headerContent);
		if (matcher.find()) {
			fileName = matcher.group();
			fileName = fileName.substring(fileName.indexOf('"') + 1, fileName.length() - 1);
		}

		return fileName;
	}
}
